package com.proj;

import java.util.*;
import java.util.stream.Collectors;

public class SimpleInfoDb implements InfoInterface {
    private TagInterface tagInterface;
    private int id = 1;
    private List<FakeInfoDao> infos = new ArrayList<>();

    SimpleInfoDb(TagInterface tagInterface) {
        this.tagInterface = tagInterface;
    }

    @Override
    public Info createInfo(String name, String content) {
        id += 1;
        infos.add(new FakeInfoDao("info-" + id, name, content));
        return new FakeInfoDao("info-" + id, name, content);
    }

    @Override
    public void updateInfo(Info info) {
        infos.stream().filter(t -> t.getId().equals(info.getId())).forEach(t -> {
            t.setName(info.getName());
            t.setContent(info.getContent());
        });
    }

    @Override
    public Collection<Info> getAllInfoWithTag(String TagId) {
        return infos.stream().filter(t -> t.tags.contains(TagId))
                .map(i -> new FakeInfoDao(i.getId(), i.getName(), i.getContent())).collect(Collectors.toList());
    }

    @Override
    public void deleteInfo(String infoId) {
        infos = infos.stream().filter(t -> !t.getId().equals(infoId)).collect(Collectors.toList());
    }

    @Override
    public void addTagForInfo(String tagId, String infoId) {
        infos.stream().filter(t -> t.getId().equals(tagId)).forEach(t -> t.tags.add(infoId));
    }

    @Override
    public void removeTagForInfo(String tagId, String infoId) {
        infos.stream().filter(t -> t.getId().equals(tagId)).forEach(t -> t.tags.remove(infoId));
    }

    @Override
    public Collection<Tag> getTagsOnInfo(String infoId) {
        FakeInfoDao info = infos.stream().filter(t -> t.getId().equals(infoId)).findFirst().orElse(null);
        if (info != null) {
            return tagInterface.getTagById(info.tags);
        }
        return Collections.emptyList();
    }

    @Override
    public Collection<Info> getInfoById(Collection<String> infoId) {
        Set<String> take = new HashSet<>(infoId);
        return infos.stream().filter(t -> take.contains(t.getId()))
                .map(i -> new FakeInfoDao(i.getId(), i.getName(), i.getContent())).collect(Collectors.toList());
    }

    @Override
    public Info getInfoByName(String infoName) {
        return infos.stream().filter(t -> t.getName().equals(infoName))
                .map(i -> new FakeInfoDao(i.getId(), i.getName(), i.getContent())).findFirst().orElse(null);
    }

    @Override
    public Collection<Info> fuzzySearch(String q, int limit) {
        return infos.stream().filter(t -> t.getName().matches(q) || t.getContent().matches(q))
                .map(i -> new FakeInfoDao(i.getId(), i.getName(), i.getContent())).collect(Collectors.toList());
    }

    @Override
    public Collection<Info> getInfoByTagUnion(String[] tags) {
        return infos.stream().filter(t -> t.tags.containsAll(Arrays.asList(tags)))
                .map(i -> new FakeInfoDao(i.getId(), i.getName(), i.getContent())).collect(Collectors.toList());
    }
}
